<% page_title "Webhooks" %>

<%= render 'projects/header', project: @project, tab: "webhooks" %>

<% inbound_webhooks = @project.webhooks %>
<section class="tabs">
  <h2>
    Inbound Webhooks
    <%= additional_info "Allows CI or source-code provider to trigger a release or deploy." %>
  </h2>

  <details>
    <summary>Callback URLs</summary>

    <dl>
      <% Samson::Integration::SOURCES.each do |source| %>
        <dt>
          <% if source == 'generic' %>
            <details>
              <summary><%= source.titleize %></summary>
              Generic endpoint to start deploys, expects post payload in the form of:
              <pre><%= <<~TEXT
                curl -H 'Content-Type: application/json' \\
                  -d '{"deploy":{"branch":"master","commit":{"sha":"abc","message":"hi"}}}' \\
                  #{integrations_generic_deploy_url(@project.token)}
               TEXT
              %></pre>
            </details>
          <% else %>
            <%= source.titleize %>
          <% end %>
        </dt>
        <dd>
          <%= send("integrations_#{source}_deploy_url", @project.token) %>
          <% if source == 'github' && token = Integrations::GithubController.secret_token %>
            <br/>
            <% if current_user.admin_for?(@project) %>
              (Set <%= link_to "secret token", "javascript:prompt('Copy this token', '#{token}')" %> in <%= link_to 'hook settings', "https://github.com/#{@project.repository_path}/settings/hooks" %>)
            <% else %>
              (Secret token required, ask a project admin)
            <% end %>
          <% end %>
        </dd>
      <% end %>
    </dl>
  </details>

  <% if hook = WebhookRecorder.read(@project) %>
    <details>
      <summary>Last request <%= relative_time Time.parse(hook.fetch(:time)) %></summary>
      <table class="table" id="latest_response">
        <tr>
          <th>Request</th>
          <td>
            <% if current_user.admin_for?(current_project) %>
              <pre><%= hook.fetch(:request_headers).map { |k,v| "#{k}: #{v}" }.join("\n") %></pre>
              Raw params:
              <pre><%= JSON.pretty_generate(hook.fetch(:request_params)) %></pre>
            <% else %>
              ... visible for admins ...
            <% end %>
          </td>
        </tr>
        <tr>
          <th>Response</th>
          <td>
            Status: <%= hook.fetch(:response_code) %><br/>
            Body:
            <% body = hook.fetch(:response_body) %>
            <pre><%= body.start_with?('{') ? (JSON.pretty_generate(JSON.parse(body)) rescue body) : body %></pre>
          </td>
        </tr>
        <tr>
          <th>Logs</th>
          <td>
            <pre><%= hook.fetch(:log) %></pre>
          </td>
        </tr>
      </table>
    </details>
  <% end %>

  <p>
    <ul>
      <li>
        <% if branch = @project.release_branch.presence %>
          <strong><%= branch %></strong> branch
        <% else %>
          No branch
        <% end %>
        &rarr;
        <%= link_to "Release", project_releases_path(@project) %>
        <%= additional_info "Samson can automatically create a new Release when a inbound webhook arrives ('Release branch' project setting)" %>
      </li>
      <li>
        <%= link_to "Release", project_releases_path(@project) %>
        &rarr;
        <% if stages = @project.stages.where(deploy_on_release: true).presence %>
          <%= safe_join stages.map { |s| link_to_resource s }, ", " %>
        <% else %>
          None
        <% end %>
        <%= additional_info "Release can trigger a deploy to selected stages ('Automatically deploy new releases' stage setting)" %>
      </li>
      <% if inbound_webhooks.empty? %>
        <li>No inbound rules configured</li>
      <% else %>
        <% inbound_webhooks.each do |webhook| %>
          <% disabled = webhook.disabled? %>
          <li class="<%= 'disabled' if disabled %>">
            <strong><%= webhook.branch.blank? ? 'Any' : webhook.branch %></strong>
            branch &rarr;
            <strong><%= webhook.stage&.name || "Deleted stage" %></strong>
            stage for:
            <%= webhook.source.humanize %>
            (
            <%= link_to disabled ? 'Enable' : 'Disable', project_webhook_path(@project, webhook, webhook: { disabled: !disabled }), method: :patch %>,
            <%= link_to_delete [@project, webhook] %>
            )
          </li>
        <% end %>
      <% end %>
    </ul>
  </p>

  <%= form_for [@project, ((@resource.is_a?(Webhook) && @resource) || Webhook.new)], html: { class: "form-inline" } do |form| %>
    <%= render 'shared/errors', object: form.object %>
    <div class="form-group">
      <%= form.text_field :branch, class: "form-control", placeholder: "Branch (Blank for any)" %>
    </div>

    &rarr;

    <div class="form-group">
      <%= form.collection_select :stage_id, @project.stages, :id, :name, {}, class: "form-control" %>
    </div>

    <div class="form-group">
      <%= form.select :source, webhook_sources_for_select(Samson::Integration::SOURCES), {}, class: "form-control" %>
    </div>

    <%= form.submit "Add", class: "btn btn-primary" %>
  <% end %>

  <% outbound_webhook_stages = OutboundWebhookStage.where(stage_id: @project.stages.map(&:id)) %>
  <h2>
    Outbound Webhooks
    <%= additional_info "POST to an external url after a deploy has finished. The request body will contain deploy, stage, and project information." %>
  </h2>
  <% if latest_deploy = @project.deploys.first %>
    <details>
      <summary>Example payload</summary>
      <pre><%= JSON.pretty_generate(OutboundWebhook.deploy_as_json(latest_deploy)) %></pre>
    </details>
  <% else %>
    <p>Deploy this project at least once to see a sample payload.</p>
  <% end %>

  <p>
    <% if outbound_webhook_stages.empty? %>
      No outbound rules configured
    <% else %>
      <ul>
        <% outbound_webhook_stages.each do |outbound_webhook_stage| %>
          <% outbound_webhook = outbound_webhook_stage.outbound_webhook %>
          <% disabled = outbound_webhook.disabled? %>
          <li class="<%= 'disabled' if disabled %>">
            <%= "#{outbound_webhook.name}: " if outbound_webhook.name? %>
            POST to
            <strong><%= outbound_webhook.url %></strong>
            <%= "(no SSL)" unless outbound_webhook.ssl? %>
            on the
            <%= link_to_resource outbound_webhook_stage.stage %>
            stage
            <strong>
            <% case outbound_webhook.auth_type %>
            <% when "Basic" %>
              <%= "with Basic Auth as #{outbound_webhook.username}" %>
            <% when "Bearer", "Token" %>
              <%= "with #{outbound_webhook.auth_type} Auth" %>
            <% end %>
            </strong>
            (
            <%# Disabling a global webhook affects all projects using it %>
            <% if outbound_webhook.global? %>
              <%= link_to_delete outbound_webhook_path(outbound_webhook, stage_id: outbound_webhook_stage.stage_id), text: 'Unlink' %>
            <% else %>
              <%= link_to disabled ? 'Enable' : 'Disable', outbound_webhook_path(outbound_webhook, stage_id: outbound_webhook_stage.stage_id, outbound_webhook: { disabled: !disabled }), method: :patch %>,
              <%= link_to_delete outbound_webhook_path(outbound_webhook, stage_id: outbound_webhook_stage.stage_id) %>
            <% end %>
            )
          </li>
        <% end %>
      </ul>
    <% end %>
  </p>

  <details>
    <summary>Add</summary>
    <%= form_for ((@resource.is_a?(OutboundWebhook) && @resource) || OutboundWebhook.new), html: {class: "form-horizontal"} do |form| %>
      <div class="form-group">
        <%= form.label "Stage", class: "col-lg-2 control-label" %>
        <div class="col-lg-4">
          <%= select_tag "stage_id", options_from_collection_for_select(@project.stages, :id, :name, form.object.outbound_webhook_stages.first&.stage_id), class: "form-control" %>
        </div>
      </div>

      <%= render "outbound_webhooks/fields", form: form %>

      <%= form.submit "Add", class: "btn btn-primary" %>
    <% end %>
  </details>

  <% if global_webhooks = OutboundWebhook.where(global: true).pluck(:name, :id).presence %>
    <details>
      <summary>Link global</summary>
      <%= form_for OutboundWebhook.new, url: connect_outbound_webhooks_path, html: {class: "form-horizontal"} do |form| %>
        <div class="form-group">
          <%= form.label "Global Webhook", class: "col-lg-2 control-label" %>
          <div class="col-lg-4">
            <%= select_tag "id", options_for_select(global_webhooks), class: "form-control" %>
          </div>
        </div>

        <div class="form-group">
          <%= form.label "Stage", class: "col-lg-2 control-label" %>
          <div class="col-lg-4">
            <%= select_tag "stage_id", options_from_collection_for_select(@project.stages, :id, :name), class: "form-control" %>
          </div>
        </div>

        <%= form.submit "Add", class: "btn btn-primary" %>
      <% end %>
    <% end %>
  </details>
</section>
